home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / mach / sun4c.md / mul.c < prev    next >
C/C++ Source or Header  |  1989-08-17  |  3KB  |  150 lines

  1. #ifdef sccsid
  2. static char     sccsid[] = "@(#)mul.c 1.5 88/02/08 SMI";
  3. #endif
  4.  
  5. /*
  6.  * Copyright (c) 1988 by Sun Microsystems, Inc.
  7.  */
  8.  
  9. /*
  10.  * This whole file refuses to lint.
  11.  */
  12. #ifndef lint
  13. #include <sun4/fpu/fpu_simulator.h>
  14. #include <sun4/fpu/globals.h>
  15.  
  16. void
  17. _fp_product(x, y, z)
  18.     unsigned        x, y;
  19.     unsigned        z[2];
  20.  
  21. /* Computes product x * y into *z[2]     */
  22.  
  23. {
  24.     union {
  25.         unsigned        ul;
  26.         unsigned short  us[2];
  27.     }
  28.                     kluge;
  29.  
  30.     unsigned        thi, tlo, tmid, t;
  31.     unsigned short  xus0, xus1, yus0, yus1;
  32.  
  33.     kluge.ul = x;
  34.     xus0 = kluge.us[0];
  35.     xus1 = kluge.us[1];
  36.     kluge.ul = y;
  37.     yus0 = kluge.us[0];
  38.     yus1 = kluge.us[1];
  39.  
  40.     thi = xus0 * yus0;
  41.     tlo = xus1 * yus1;
  42.  
  43.     tmid = xus1 * yus0;
  44.     thi += tmid >> 16;
  45.     tmid = tmid << 16;
  46.     t = tmid + tlo;
  47.     if ((t < tmid) && (t < tlo))
  48.         thi++;
  49.     tlo = t;
  50.  
  51.     tmid = xus0 * yus1;
  52.     thi += tmid >> 16;
  53.     tmid = tmid << 16;
  54.     t = tmid + tlo;
  55.     if ((t < tmid) && (t < tlo))
  56.         thi++;
  57.     tlo = t;
  58.  
  59.     z[0] = thi;
  60.     z[1] = tlo;
  61.  
  62. }
  63.  
  64. void
  65. _fp_mul(px, py, pz)
  66.     unpacked       *px, *py, *pz;
  67.  
  68. {
  69.     unpacked       *pt;
  70.     unsigned        t, tacc[2], acc[4];    /* Product accumulator. */
  71.  
  72.     if ((int) px->fpclass < (int) py->fpclass) {
  73.         pt = px;
  74.         px = py;
  75.         py = pt;
  76.     }
  77.     /* Now class(x) >= class(y).  */
  78.  
  79.     *pz = *px;
  80.     pz->sign = px->sign ^ py->sign;
  81.  
  82.     switch (px->fpclass) {
  83.     case fp_quiet:
  84.     case fp_signaling:
  85.     case fp_zero:
  86.         return;
  87.     case fp_infinity:
  88.         if (py->fpclass == fp_zero) {
  89.             fpu_error_nan(pz);
  90.             pz->fpclass = fp_quiet;
  91.         }
  92.         return;
  93.     case fp_normal:
  94.         if (py->fpclass == fp_zero) {
  95.             pz->fpclass = fp_zero;
  96.             return;
  97.         }
  98.     }
  99.  
  100.     /* Now x and y are both normal or subnormal. */
  101.  
  102.     pz->exponent = px->exponent + py->exponent + 1;
  103.  
  104.     _fp_product(px->significand[1], py->significand[1], tacc);
  105.     acc[2] = tacc[0];
  106.     acc[3] = tacc[1];
  107.  
  108.     _fp_product(px->significand[0], py->significand[0], tacc);
  109.     acc[0] = tacc[0];
  110.     acc[1] = tacc[1];
  111.  
  112.     _fp_product(px->significand[1], py->significand[0], tacc);
  113.     t = acc[2] + tacc[1];
  114.     if ((t < acc[2]) && (t < tacc[1])) {    /* Propagate carry. */
  115.         acc[1]++;
  116.         if (acc[1] == 0)
  117.             acc[0]++;
  118.     }
  119.     acc[2] = t;
  120.     t = acc[1] + tacc[0];
  121.     if ((t < acc[1]) && (t < tacc[0])) {    /* Propagate carry. */
  122.         acc[0]++;
  123.     }
  124.     acc[1] = t;
  125.  
  126.     _fp_product(px->significand[0], py->significand[1], tacc);
  127.     t = acc[2] + tacc[1];
  128.     if ((t < acc[2]) && (t < tacc[1])) {    /* Propagate carry. */
  129.         acc[1]++;
  130.         if (acc[1] == 0)
  131.             acc[0]++;
  132.     }
  133.     acc[2] = t;
  134.     t = acc[1] + tacc[0];
  135.     if ((t < acc[1]) && (t < tacc[0])) {    /* Propagate carry. */
  136.         acc[0]++;
  137.     }
  138.     acc[1] = t;
  139.  
  140.     pz->significand[0] = acc[0];
  141.     pz->significand[1] = acc[1];
  142.     pz->significand[2] = acc[2];
  143.     if (acc[3])
  144.         pz->significand[2] |= 1;
  145.  
  146.     fpu_normalize(pz);
  147.  
  148. }
  149. #endif /* lint */
  150.